package com.rightsidetech.mall.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.rightsidetech.mall.dto.log.CommodityMarketName;
import com.rightsidetech.mall.dto.log.MallLogInfoDto;
import com.rightsidetech.mall.dto.request.*;
import com.rightsidetech.mall.entity.MallCommodityLog;
import com.rightsidetech.mall.entity.MallCommodityWithBLOBs;
import com.rightsidetech.mall.entity.MallIntegralCommodity;
import com.rightsidetech.mall.mapper.MallCommodityLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
public class MallReceiverRedisMessage {

    @Resource
    private MallCommodityLogMapper mallCommodityLogMapper;

    public void mallLogReceiver(String jsonStr){
        MallLogInfoDto dto = JSONUtil.toBean(jsonStr, MallLogInfoDto.class);
        Object oldParam = dto.getOldParam();
        MallCommodityLog record = getMallCommodityLog(dto);
        if(ObjectUtil.isEmpty(oldParam)){
            //新增或上下架
            StringBuilder builder = new StringBuilder();
            builder.append(dto.getOperateType()).append("了【").append(ObjectUtil.isEmpty(dto.getNewParam()) ? "": dto.getNewParam().toString())
                    .append("】");
            record.setDetails(builder.toString());
            mallCommodityLogMapper.insertSelective(record);
        }else {
            if(dto.getCommodityMarketName().equals(CommodityMarketName.BATTERY_MALL.getMallType())){
                //编辑电池商城
                updateBatteryMall(dto,record);
            }else if(dto.getCommodityMarketName().equals(CommodityMarketName.INTEGRAL_MALL.getMallType())){
                //编辑积分商城
                updateIntegralMall(dto,record);
            }
        }
    }

    private void updateIntegralMall(MallLogInfoDto dto, MallCommodityLog record) {
        IntegralUpReq req = JSONUtil.toBean(dto.getNewParam().toString(),IntegralUpReq.class);
        MallIntegralCommodity commodity = JSONUtil.toBean(dto.getOldParam().toString(),MallIntegralCommodity.class);
        StringBuilder builder = new StringBuilder();
        boolean isUpdate = false;
        String commodityName = dto.getCommodityName();
        if(!req.getPrice().equals(commodity.getPrice())){
            builder.append("积分价格").append("【").append(commodity.getPrice().divide(new BigDecimal(100))).append("】修改成了【").append(req.getPrice().divide(new BigDecimal(100))).append("】");
            isUpdate = true;
        }
        if(commodity.getSpecs() != null){
            record.setCommodityName(new StringBuilder().append(commodityName).append("【").append(commodity.getSpecs()).append("】").toString());
        }
        DetailSpecsReq specs = req.getSpecs();
        if(ObjectUtil.isNotEmpty(specs)){
            String spec = specs.getValueList().stream().map(DetailSpecsValueReq::getSpecsValue).collect(Collectors.joining("、"));
            record.setCommodityName(new StringBuilder().append(commodityName).append("【").append(spec).append("】").toString());
            if(!spec.equals(commodity.getSpecs())){
                builder.append("将积分商品规格【").append(commodity.getSpecs() == null ? " " : commodity.getSpecs()).append("】修改成了【")
                        .append(spec).append("】");
                isUpdate = true;
            }
        }
        if(!req.getStock().equals(commodity.getStock())){
            builder.append("积分库存").append("【").append(commodity.getStock()).append("】修改成了【").append(req.getStock()).append("】");
            isUpdate = true;
        }
        if(isUpdate){
            String details = builder.toString();
            if(details.length() > 1500){
                log.error("此操作字段长度过长不记录 积分商品:{} 记录:{}",dto.getCommodityName(),details);
                return;
            }
            record.setDetails(details);
            mallCommodityLogMapper.insertSelective(record);
        }
    }

    private void updateBatteryMall(MallLogInfoDto dto,MallCommodityLog record){
        CommodityUpReq req = JSONUtil.toBean(dto.getNewParam().toString(), CommodityUpReq.class);
        MallCommodityWithBLOBs commodity = JSONUtil.toBean(dto.getOldParam().toString(), MallCommodityWithBLOBs.class);
        StringBuilder builder = new StringBuilder();
        boolean isUpdate = false;
        if(!req.getIsInNew().equals(commodity.getIsInNew())){
            builder.append("是否支持已旧换新改成了【").append(req.getIsInNew() == 0 ? "支持": "不支持").append("】");
            isUpdate = true;
        }
        if(req.getInNewPrice() != null && !req.getInNewPrice().equals(commodity.getInNewPrice())){
            builder.append("将已旧换新价格从【").append(ObjectUtil.isEmpty(commodity.getInNewPrice()) ? "0": commodity.getInNewPrice().divide(new BigDecimal(100))).append("】")
                    .append("改成了").append("【").append(req.getInNewPrice().divide(new BigDecimal(100))).append("】");
            isUpdate = true;
        }
        if(!req.getPrice().equals(commodity.getPrice())){
            builder.append("将价格从【").append(commodity.getPrice().divide(new BigDecimal(100))).append("】")
                    .append("改成了").append("【").append(req.getPrice().divide(new BigDecimal(100))).append("】");
            isUpdate = true;
        }
        if(StrUtil.isNotBlank(commodity.getSpecsDetailJson())){
            if(CollUtil.isEmpty(req.getSpecsList())){
                builder.append("将商品【").append(dto.getCommodityName()).append("】")
                        .append("规格").append("删除");
            }else {
                List<CommoditySaveSpecsReq> newSpecsList = req.getSpecsList();
                List<CommoditySaveSpecsReq> specsList = JSONUtil.toList(commodity.getSpecsDetailJson(), CommoditySaveSpecsReq.class);
                l1:for (CommoditySaveSpecsReq oldSpecs : specsList) {
                    for (CommoditySaveSpecsReq newSpecs : newSpecsList) {
                        if(newSpecs.getCode().equals(oldSpecs.getCode())){
                            String collect = oldSpecs.getValueList().stream().map(DetailSpecsValueReq::getSpecsValue).collect(Collectors.joining("、"));
                            if(!newSpecs.getPrice().equals(oldSpecs.getPrice())){
                                builder.append("将规格【").append(collect).append("】价格由【").append(oldSpecs.getPrice().divide(new BigDecimal(100))).append("】改为")
                                .append("【").append(newSpecs.getPrice().divide(new BigDecimal(100))).append("】");
                                isUpdate = true;
                            }
                            if(newSpecs.getInNewPrice() != null && !newSpecs.getInNewPrice().equals(oldSpecs.getInNewPrice())){
                                builder.append("将规格【").append(collect).append("】已旧换新价格由【").append(oldSpecs.getInNewPrice().divide(new BigDecimal(100))).append("】改为")
                                        .append("【").append(newSpecs.getInNewPrice().divide(new BigDecimal(100))).append("】");
                                isUpdate = true;
                            }
                            continue l1;
                        }
                    }
                }
            }
        }
        if(isUpdate){
            String details = builder.toString();
            if(details.length() > 1500){
                log.error("此操作字段长度过长不记录 商品:{} 记录:{}",dto.getCommodityName(),details);
                return;
            }
            record.setDetails(details);
            mallCommodityLogMapper.insertSelective(record);
        }

    }

    private MallCommodityLog getMallCommodityLog(MallLogInfoDto dto){
        MallCommodityLog record = new MallCommodityLog();
        record.setLoginInfoId(dto.getLoginInfoId());
        record.setLoginName(dto.getLoginName());
        record.setCommodityMarketName(dto.getCommodityMarketName());
        record.setOperateType(dto.getOperateType());
        record.setCommodityName(dto.getCommodityName());
        record.setUrl(dto.getUrl());
        record.setCreatedAt(DateUtil.parse(dto.getCreatedAt(),"yyyy-MM-dd HH:mm:ss"));
        String s = JSONUtil.toJsonStr(dto.getParam());
        record.setRequestParam(StrUtil.isBlank(s) || s.length() > 500 ? null : s);
        record.setCommodityName(dto.getCommodityName());
        return record;
    }
}
